package org.wheel.plugins.toolkit.sql.core;

import java.util.Map;

/**
 * SQL片段
 */
public interface SqlSegment {
    String getSql();

    /**
     * 把本片段内部已经生成的所有 :pX 占位符 key 登记到 ParamBank。
     * 不负责生成序号，只负责“我有哪些 key”。
     * 一、保留原因：<br>
     * 1. 统一契约：所有片段（Where / Function / Having …）都实现 SqlSegment，框架可在渲染前统一遍历：
     * <pre>{@code
     * for (SqlSegment seg : allSegments) {
     *     seg.collectParamMap(globalBank, prefix); // 只登记 key
     * }
     * }</pre>
     * 2. 插件扩展：用户自定义 SqlSegment 时，只要重写 collectParamMap 把内部 :key 写进 ParamBank，就能无缝接入现有生命周期。<br>
     * 3. key 冲突检测：集中遍历阶段可做一次「重复 key 断言」，提前失败。<br>
     * 二、什么时候需要重写<br>
     * 只有手动拼字符串的片段才需要登记，例如：<pre>{@code
     * class RawSegment implements SqlSegment {
     *     private final String raw; // 已含 :p0,:p1
     *     public void collectParamMap(ParamBank bank, String prefix) {
     *         // 解析 raw，把所有 :pX 提取出来，确保 bank 里有对应 key
     *         ReUtil.findAll(":(\\w+)", raw, m -> bank.putIfAbsent(m.group(1), null));
     *     }
     * }
     * }</pre>
     * 结论： 接口保留，职责弱化，既不破坏现有流程，也给扩展留一条路。
     * <pre>
     * | 场景                                             | 是否需要 collectParamMap             |<br>
     * | ----------------------------------------------- | -----------------------------       |<br>
     * | 框架内置片段（WhereSegment、FunctionBuilder 等）   | 默认空实现**即可，已实时 `nextParam()`  |<br>
     * | 用户自定义片段且 手动拼 `:key`                     | 重写登记 key                          |<br>
     * | 未来插件扩展                                     | 保留接口即可接入                        |<br>
     * </pre>
     * @param globalMap
     * @param prefix
     */
    default void collectParamMap(Map<String, Object> globalMap, String prefix){};
}